﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Markup;

namespace System.Windows.Media.Media3D10
{
    /// <summary>
    /// Collection de modèles 3D. 
    /// </summary>
    [ContentProperty("Children")]
    public sealed class Model3D10Group : Model3D10
    {
        #region Dependency Properties
        /// <summary>
        /// Identifie la propriété de dépendance <see cref="Children"/>.
        /// </summary>
        public static readonly DependencyProperty ChildrenProperty =
            DependencyProperty.Register("Children", typeof(Model3D10Collection), typeof(Model3D10Group));
        #endregion

        #region Constructors
        /// <summary>
        /// Initialise une nouvelle instance de la classe <see cref="Model3D10Group"/>
        /// </summary>
        public Model3D10Group()
        {
            SetValue(ChildrenProperty, new Model3D10Collection());
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Obtient ou définit une collection d'objets <see cref="Model3D10"/> Il s'agit d'une propriété de dépendance. 
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227", Justification="Dependency Property")]
        public Model3D10Collection Children 
        {
            get { return (Model3D10Collection)GetValue(ChildrenProperty); } 
            set { SetValue(ChildrenProperty, value); } 
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Crée un clone modifiable de ce <see cref="Model3D10Group"/>, en créant des copies complètes des valeurs de cet objet.
        /// Lors de la copie de propriétés de dépendance, cette méthode copie les références de ressources et les liaisons de données (même si elles ne peuvent plus être résolues), mais pas les animations ni leurs valeurs actuelles.
        /// </summary>
        /// <returns>
        /// Clone modifiable de l'objet actuel.
        /// La valeur de la propriété <see cref="Freezable.IsFrozen"/> de l'objet cloné est false, même si la valeur de la propriété <see cref="Freezable.IsFrozen"/> de la source est true.
        /// </returns>
        public new Model3D10Group Clone()
        {
            return (base.Clone() as Model3D10Group);
        }

        /// <summary>
        /// Crée un clone modifiable de ce <see cref="CloneCurrentValue"/>, en créant des copies complètes des valeurs actuelles de cet objet.
        /// Contrairement à leurs valeurs actuelles, les références de ressources, les liaisons de données et les animations ne sont pas copiées.
        /// </summary>
        /// <returns>
        /// Clone modifiable de l'objet actuel.
        /// La valeur de la propriété <see cref="Freezable.IsFrozen"/> de l'objet cloné est false, même si la valeur de la propriété <see cref="Freezable.IsFrozen"/> de la source est true.
        /// </returns>
        public new Model3D10Group CloneCurrentValue()
        {
            return (base.CloneCurrentValue() as Model3D10Group);
        }
        #endregion

        #region Model3D10 Overrides
        /// <summary>
        /// En cas de substitution dans une classe dérivée, participe au dessin des objets dans le pipeline DirectX10
        /// </summary>
        /// <param name="context">Contexte de dessin.</param>
        /// <exception cref="ArgumentNullException">Soulevée si le contexte est null.</exception>
        protected override void OnDraw(DrawingContext context)
        {
            if (context == null) throw new ArgumentNullException("context");

            base.OnDraw(context);
            SlimDX.Matrix world = context.WorldMatrix;

            foreach (IDrawable model in Children)
            {
                context.WorldMatrix = world;
                model.Draw(context);
            }
        }
        #endregion

        #region Freezable Implementation
        /// <summary>
        /// Une fois implémentée dans une classe dérivée, initialise une nouvelle instance de la classe dérivée <see cref="Freezable"/>. 
        /// </summary>
        /// <returns>Nouvelle instance.</returns>
        protected override Freezable CreateInstanceCore()
        {
            return new Model3D10Group();
        }
        #endregion
    }
}
